package com.powernode.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.powernode.constant.ManagerConstants;
import com.powernode.ex.handler.BusinessException;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.domain.SysMenu;
import com.powernode.mapper.SysMenuMapper;
import com.powernode.service.SysMenuService;

@Service
@CacheConfig(cacheNames = "com.powernode.service.impl.SysMenuServiceImpl")
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;

    /**
     * 根据用户标识查询菜单权限集合
     *
     * @param loginUserId
     * @return
     */
    @Override
    @Cacheable(key = "#loginUserId")
    public Set<SysMenu> queryUserMenuListByUserId(Long loginUserId) {
        // 根据用户标识查询菜单集合
        Set<SysMenu> menus = sysMenuMapper.selectUserMenuListByUserId(loginUserId);
        return transformTree(menus, 0L);
    }


    /**
     * 将菜单集合转换为树结构
     * 1. 已知菜单深度 <= 2
     * 2. 未知菜单深度
     *
     * @param menus
     * @param pid
     * @return
     */
    private Set<SysMenu> transformTree(Set<SysMenu> menus, long pid) {
       /* //获取菜单的根节点集合
        Set<SysMenu> roots = menus.stream().filter(m -> m.getParentId().equals(pid)).collect(Collectors.toSet());

        //循环遍历根节点
        roots.forEach(root -> {
            Set<SysMenu> child = menus.stream().filter(m -> m.getParentId().equals(root.getMenuId()))
                    .collect(Collectors.toSet());
            root.setList(child);
        });
      */

        //未知菜单深度
        //获取根节点集合
        Set<SysMenu> roots = menus.stream().filter(m -> m.getParentId().equals(pid))
                .collect(Collectors.toSet());
        //循环节点集合
        roots.forEach(r -> r.setList(transformTree(menus, r.getMenuId())));
        return roots;
    }


    /**
     * 查询所有权限集合
     *
     * @return
     */
    @Override
    @Cacheable(key = ManagerConstants.SYS_ALL_MENU_KEY)
    public List<SysMenu> queryAllSysMenuList() {
        return sysMenuMapper.selectList(null);
    }

    /**
     * 新增权限
     *
     * @param sysMenu
     * @return
     */
    @Override
    @CacheEvict(key = ManagerConstants.SYS_ALL_MENU_KEY)    //清除缓存
    public Boolean saveSysMenu(SysMenu sysMenu) {
        return sysMenuMapper.insert(sysMenu) > 0;
    }

    /**
     * 修改权限
     *
     * @param sysMenu
     * @return
     */
    @Override
    @CacheEvict(key = ManagerConstants.SYS_ALL_MENU_KEY)
    public Boolean modifySysMenu(SysMenu sysMenu) {
        //获取菜单类型
        Integer type = sysMenu.getType();
        if (0 == type) {
            sysMenu.setParentId(0L);
        }
        return sysMenuMapper.updateById(sysMenu) > 0;
    }

    /**
     * 删除权限
     *
     * @param menuId
     * @return
     */
    @Override
    @CacheEvict(key = ManagerConstants.SYS_ALL_MENU_KEY)
    public Boolean removeSysMenuById(Long menuId) {
        // 查询当前权限节点的子节点
        List<SysMenu> sysMenuList = sysMenuMapper.selectList(new LambdaQueryWrapper<SysMenu>()
                .eq(SysMenu::getParentId, menuId)
        );
        // 判断是否包含子节点
        if (CollectionUtil.isNotEmpty(sysMenuList) && sysMenuList.size() != 0) {
            throw new BusinessException("当前节点包含子节点，不可删除");
        }
        // 当前菜单节点不包含子节点,删除权限节点
        return sysMenuMapper.deleteById(menuId) > 0;
    }
}
